
/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , http = require('http')
  , path = require('path')
  , model = require('./models');

var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

app.configure(function(){
  app.set('port', process.env.PORT || 80);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser({uploadDir:'./uploads'}));
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

routes(app);
server.listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
var pieTime = function(){
  var curTime = new Date();
  var year = curTime.getFullYear();
  var month = curTime.getMonth()+1;
  var date = curTime.getDate();
  var day = curTime.getDay()+1;
  var hour = curTime.getHours();
  var minute = curTime.getMinutes();
  var second = curTime.getSeconds();
  var result = year+':'+month+':'+date+':'+day+':'+hour+':'+minute+':'+second;
  return result;
}
var userModel = model.userModel;
var saveUser = function(user,reason){
  user.save(function(err){
    if(err){
      console.log(reason+' 保存用户出错:'+user.puid+' err= '+err);
    }
  })
};
var newClient=function(user,clientId,socketId){
  var len = user.clientList.push({
    'clientId':clientId,
    'socketId':socketId,
    'nextMessageIndex':0,
    'messageReplied':true
  });
  clientConnect(user,len-1,socketId);
};
var clientConnect=function(user,clientPlace,socketId){
  user.onlineNum++;
  user.clientList[clientPlace].socketId = socketId;
  sendMessage(user);
  saveUser(user,'clientConnect');
};
var pushMessage=function(clientId,fromUser,toUser,contentType,content){
  var fromId = fromUser.messageList.length;
  var toId = toUser.messageList.length;
  var thisMessage = {
    'status': 0,
    'from': fromUser.puid,
    'fromId': fromId,
    'to': toUser.puid,
    'toId': toId,
    'contentType': contentType,
    'content': content,
    'time': pieTime()
  };
  var clientNum = fromUser.messageList.push(thisMessage);
  for(var i = 0; i < clientNum; i++){
    fromUser.clientList[i].nextMessageIndex++;
    break;
  }
  toUser.messageList.push(thisMessage);
  saveUser(fromUser,'pushMessage fromUser'+fromUser.puid);
  saveUser(toUser,'pushMessage toUser'+toUser.puid);
  sendMessage(fromUser);
  sendMessage(toUser);
};
var sendMessage=function(user){
  var clientNum = user.clientList.length;
  var changed = false;
  for(var i = 0 ;i < clientNum; i++){
    if(user.clientList[i].nextMessageIndex<user.messageList.length&&user.clientList[i].socketId
      &&user.clientList[i].messageReplied){
      var newMessage = user.messageList[user.clientList[i].nextMessageIndex];
      var socket = io.sockets.sockets[user.clientList[i].socketId];
      if(!socket){break;}
      socket.emit('pieMessage',{'content':newMessage});
      user.clientList[i].messageReplied=false;
      changed = true;
    }
  }
  if(changed){
    saveUser(user,'sendMessage');
  }
};
var receiveMessage=function(user,clientId,messageId,type){
  /*console.log('messageReceived by '+clientId+' id:'+messageId+' type:'+type);*/
  if(type == 1){
    /*exports.userModel  = userModel;
      type=1表示消息由用户发出,否则表示消息由用户接收
    */
  }
  else{
    user.messageList[messageId].status = 1;
    var from = user.messageList[messageId].from;
    var fromId = user.messageList[messageId].fromId;
    userModel.findOne({'puid':from},function(err,target){
      if(err){
        logError(err);
        return;
      }
      if(target){
        target.messageList[fromId].status = 1;
        target.save(function(err){
          if(err){
            logError(err);
          }
        })
      }
    });
  }
  var clientNum = user.clientList.length;
  for(var i = 0; i < clientNum; i++){
    if(user.clientList[i].clientId == clientId){
      user.clientList[i].messageReplied = true;
      user.clientList[i].nextMessageIndex++;
      saveUser(user,'receiveMessage');
      sendMessage(user,'receiveMessage');
      return;
    }
  }
  console.log('receiveMessage error'+user.puid);
};
var disconnect=function(user,clientId,socketId){
  var clientNum = user.clientList.length;
  for(var i = 0; i < clientNum; i++){
    if(user.clientList[i].clientId == clientId&&user.clientList[i].socketId == socketId){
      user.clientList[i].socketId = null;
      user.onlineNum--;
      saveUser(user,'disconnect');
      return;
    }
  }
};
var elemIn=function(elem,array){
  var len=array.length;
  for(var i = 0; i < len; i++){
    if(array[i] == elem){
      return true;
    }
  }
  return false;
}
var logError=function(err){
  console.log('连接数据库出错:'+err);
}
io.on('connection',function(socket){
  var puid = null;   //当前连接对应唯一用户的puid
  var clientId = null;  //当前连接对应唯一平台的clientId,一个用户有可能在同一时刻从不同平台连接服务器
  var verified=false;  //标记当前连接是否经过验证,若为false不响应任何请求
  socket.emit('connected',{id:socket.id});
  socket.on('login',function(data){
    /*
      此处需要对用户进行验证
    */
    verified=true;
    if(puid||clientId){return;}
    puid = data.puid;
    clientId = data.clientId;
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err);
        return;
      }
      if(user){
        var clientPlace = -1;
        var clientNum = user.clientList.length;
        for(var i = 0; i < clientNum; i++){
          if(user.clientList[i].clientId == clientId){
            clientPlace = i;
            break;
          }
        }
        if(clientPlace>=0){
          clientConnect(user,clientPlace,socket.id);
        }
        else{
          clientId = Math.floor(10000000*Math.random());
          var array = [];
          for(var i = 0; i < clientNum; i++){
            array.push(user.clientList[i].clientId);
          }
          while(elemIn(clientId,array)){
            clientId = Math.floor(10000000*Math.random());
          }
          newClient(user,clientId,socket.id);
          socket.emit('firstLogin',{'clientId':clientId});
        }
      }
      else{
        var newUser  = new userModel({
          'puid':data.puid,
          'onlineNum':0,
          'messageList':[],
          'clientList':[]
        })
        newUser.save(function(err){
          if(err){
            logError(err);
            return;
          }
          else{
            clientId = Math.floor(10000000*Math.random());
            newClient(newUser,clientId,socket.id);
            socket.emit('firstLogin',{'clientId':clientId});
          }
        })
      }
    })
  });
  socket.on('pieTalk',function(data){
    if(!verified){return;}
    /*
      这里需要验证是否有聊天的权利
    */
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err);
        return;
      }
      if(user){
        userModel.findOne({'puid':data.targetId},function(err,target){
          if(err){
            logError(err);
            return;
          }
          if(target){
            pushMessage(clientId,user,target,data.contentType,data.content);
          }
        })
      }
    });
  });
  socket.on('messageReceived',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err);
        return;
      }
      if(user){
        receiveMessage(user,clientId,data.messageId,data.type);
      }
    });
  });
  socket.on('disconnect',function(){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err);
        return;
      }
      if(user){
        disconnect(user,clientId,socket.id);
      }
    });
  });
});